package com.woniuxy.moneyapp.app.controller;


import com.alipay.api.AlipayApiException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.commons.exception.MyException;
import com.woniuxy.commons.param.TransfesInfo;
import com.woniuxy.commons.util.*;
import com.woniuxy.moneyapp.app.controller.form.RechargeStateInfo;
import com.woniuxy.moneyapp.client.CashoutRecordClient;
import com.woniuxy.moneyapp.client.param.CashoutDto;
import com.woniuxy.moneyapp.client.param.CashoutForm;
import com.woniuxy.moneyapp.common.enums.PaymentRelated;
import com.woniuxy.moneyapp.common.enums.SchemaCode;
import com.woniuxy.moneyapp.common.exception.code.FundExceptionCode;
import com.woniuxy.moneyapp.common.utils.CommonUtil;
import com.woniuxy.moneyapp.infra.model.PayRecord;
import com.woniuxy.moneyapp.service.CashoutRecordService;
import com.woniuxy.moneyapp.service.PayRecordService;
import com.woniuxy.ptapp.client.ClassesOrderClient;
import com.woniuxy.userapp.client.FrontAccountClient;
import com.woniuxy.userapp.client.VenueClient;
import com.woniuxy.userapp.client.param.ChangeAccountMoneyInfo;
import com.woniuxy.userapp.client.param.DepositInfo;
import com.woniuxy.userapp.client.param.FrontAccountInfo;
import com.woniuxy.userapp.client.param.VenueInfo;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author seven
 * @since 2022-08-01
 */
@RestController
public class CashoutRecordController implements CashoutRecordClient {


    @Resource
    private FrontAccountClient uc;

    @Resource
    private VenueClient vc;

    @Resource
    private PayRecordService pr;

    @Resource
    private RocketMQTemplate rt;

    private ObjectMapper om = new ObjectMapper();



    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public Result<CashoutDto> cashout(CashoutForm cashAmount) throws AlipayApiException, JsonProcessingException {
        //根据token 查用户id 用户名
        LoginUserDto userDto = GetTokenUserLogin.getTokenUserLogin();
        //前台帐户id
        Integer a = userDto.getLoginId();
        //前台帐户用户名
        String userName = userDto.getLoginName();

        if(Long.parseLong(cashAmount.getCashAmount())<=0)
            throw new MyException
                    (FundExceptionCode.CASH_AMOUNT_ERROR.getCode(),
                            FundExceptionCode.CASH_AMOUNT_ERROR.getMsg());

        Result<FrontAccountInfo> frontAccountInfoResult = uc.loadUserByAccountId(a);
        if(new BigDecimal(cashAmount.getCashAmount()).compareTo(frontAccountInfoResult.getData().getMoney())>0)
            throw new MyException(FundExceptionCode.BALANCE_NOT_ENOUGH.getCode(),FundExceptionCode.BALANCE_NOT_ENOUGH.getMsg());

        Result<VenueInfo> venueByAccountId = vc.findVenueByAccountId(a);
        System.out.println(venueByAccountId.getData());

        String password = frontAccountInfoResult.getData().getPassword();
        //判断是否是场馆账户
        if(venueByAccountId.getData()==null)
            throw new MyException(FundExceptionCode.USER_NOT_FOUND.getCode(),FundExceptionCode.USER_NOT_FOUND.getMsg());
        if(!userName.equals(venueByAccountId.getData().getUserName()))
            throw new MyException(FundExceptionCode.VENUE_NOT_FOUND.getCode(),FundExceptionCode.VENUE_NOT_FOUND.getMsg());
        Result<FrontAccountInfo> data = uc.loadUserByAccountId(a);
        if(data.getCode()!=200)
            throw new MyException(FundExceptionCode.DAO_ERROR.getCode(),FundExceptionCode.DAO_ERROR.getMsg());
        FrontAccountInfo acc = data.getData();
        if(!new BCryptPasswordEncoder().matches(cashAmount.getPwd(),password))
            throw new MyException(FundExceptionCode.PWD_WRONG.getCode(),FundExceptionCode.PWD_WRONG.getMsg());
        BigDecimal cashaaa = new BigDecimal(cashAmount.getCashAmount());
        //支付表记录 提现表里记录


        //支付表
        PayRecord payRecord = new PayRecord();
        payRecord.setCreateTime(LocalDateTime.now());
        payRecord.setScence(SchemaCode.CASHOUT_CODE.getNum());
        payRecord.setPaymentWay(PaymentRelated.ALIPAY_NAME.getDesc());
        payRecord.setCashAmount(cashaaa);
        payRecord.setState(0);
        String payNum = CommonUtil.getRechargeCode(SchemaCode.SERIAL_CODE.getNum());
        payRecord.setPayNum(payNum);
        if(!pr.save(payRecord))
            throw new MyException(FundExceptionCode.DAO_ERROR.getCode(),FundExceptionCode.DAO_ERROR.getMsg());

        //支付宝转转账
        VenueInfo infoo = venueByAccountId.getData();
        if(infoo.getAlipayCode()==null)
            throw new MyException(FundExceptionCode.ALIPAY_CODE_NULL.getCode(),FundExceptionCode.ALIPAY_CODE_NULL.getMsg());
        TransfesInfo transfesInfo = new TransfesInfo();
        transfesInfo.setPayee_account(infoo.getAlipayCode());
        transfesInfo.setAmount(cashAmount.getCashAmount());
        transfesInfo.setOrder_title("账号id为"+a+"提现业务");
        transfesInfo.setRemark("账号id为"+a+"提现业务");
        Result<String> transfer = CommonUtil.Transfer(transfesInfo);
        if(transfer.getCode()!=200)
            throw new MyException(FundExceptionCode.DAO_ERROR.getCode(),FundExceptionCode.DAO_ERROR.getMsg());

        //改余额 之前余额支付的接口
        DepositInfo depositInfo = new DepositInfo();
        depositInfo.setAccountId(infoo.getFrontAccountId());
        depositInfo.setPassword(cashAmount.getPwd());
        depositInfo.setAmount(new BigDecimal(cashAmount.getCashAmount()));
        Result deposit = uc.deposit(depositInfo);

        if(deposit.getCode()==500)
            throw new MyException(FundExceptionCode.DAO_ERROR.getCode(),FundExceptionCode.DAO_ERROR.getMsg());


        //记录信息
        RechargeStateInfo msg = new RechargeStateInfo();
        msg.setSericalNum(payNum);
        msg.setOut_trade_no(transfer.getData());
        msg.setScence(SchemaCode.CASHOUT_CODE.getNum());
        msg.setPayment(PaymentRelated.ALIPAY_NAME.getDesc());
        msg.setCashAmount(new BigDecimal(cashAmount.getCashAmount()));
        msg.setState(1);
        msg.setPayeeId(a);
        msg.setPayeeName(userName);

        //成功 异步回调更新 提现表状态更新
        rt.asyncSend("msgsend:add_info", MessageBuilder.withPayload(msg).build(),
                new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("发送成功: " + sendResult);
                    }

                    @Override
                    public void onException(Throwable e) {
                        System.out.println("发送失败: " + e.getMessage());
                    }
                });

        //将信息返回前端
        CashoutDto cashoutDto = new CashoutDto();
        cashoutDto.setScence(SchemaCode.CASHOUT_CODE.getNum());
        cashoutDto.setPaymentWay(PaymentRelated.ALIPAY_NAME.getDesc());
        cashoutDto.setCashAmount(cashaaa);
        cashoutDto.setOrderNum(transfer.getData());
        cashoutDto.setState(1);

        return new Result<CashoutDto>().setCode(200).setMsg("提现成功").setData(cashoutDto);
    }
}



